#include <iostream>
#include<mpi.h>
#include<fstream>
#include<string>
#include<vector>
#include<sys/time.h>
#include<math.h>
#include<arm_neon.h>

#include<omp.h>
using namespace std;
int pThreadNum = 1;
bool* isNull;



string getbeiAddr(int which)
{
    switch (which) {
    case 1:
        return "/home/sTest/2110935/data/Groebner/1_130_22_8/2.txt";
    case 2:
        return "/home/sTest/2110935/data/Groebner/2_254_106_53/2.txt";
    case 3:
        return "/home/sTest/2110935/data/Groebner/3_562_170_53/2.txt";
    case 4:
        return "/home/sTest/2110935/data/Groebner/4_1011_539_263/2.txt";
    case 5:
        return "/home/sTest/2110935/data/Groebner/5_2362_1226_453/2.txt";
    case 6:
        return "/home/sTest/2110935/data/Groebner/6_3799_2759_1953/2.txt";
    case 7:
        return "/home/sTest/2110935/data/Groebner/7_8399_6375_4535/2.txt";
    case 8:
        return "/home/sTest/2110935/data/Groebner/8_23045_18748_14325/2.txt";
    case 9:
        return "/home/sTest/2110935/data/Groebner/9_37960_29304_14921/2.txt";
    case 10:
        return "/home/sTest/2110935/data/Groebner/10_43577_39477_54274/2.txt";
    case 11:
        return "/home/sTest/2110935/data/Groebner/11_85401_5724_756/2.txt";
    default:
        return "";
    }
}
string getziAddr(int which)
{
    switch (which) {
    case 1:
        return "/home/sTest/2110935/data/Groebner/1_130_22_8/1.txt";
    case 2:
        return "/home/sTest/2110935/data/Groebner/2_254_106_53/1.txt";
    case 3:
        return "/home/sTest/2110935/data/Groebner/3_562_170_53/1.txt";
    case 4:
        return "/home/sTest/2110935/data/Groebner/4_1011_539_263/1.txt";
    case 5:
        return "/home/sTest/2110935/data/Groebner/5_2362_1226_453/1.txt";
    case 6:
        return "/home/sTest/2110935/data/Groebner/6_3799_2759_1953/1.txt";
    case 7:
        return "/home/sTest/2110935/data/Groebner/7_8399_6375_4535/1.txt";
    case 8:
        return "/home/sTest/2110935/data/Groebner/8_23045_18748_14325/1.txt";
    case 9:
        return "/home/sTest/2110935/data/Groebner/9_37960_29304_14921/1.txt";
    case 10:
        return "/home/sTest/2110935/data/Groebner/10_43577_39477_54274/1.txt";
    case 11:
        return "/home/sTest/2110935/data/Groebner/11_85401_5724_756/1.txt";
    default:
        return "";
    }
}
int getHang(int which)
{
    switch (which)
    {
    case 1:
        return 8;
    case 2:
        return 53;
    case 3:
        return 53;
    case 4:
        return 263;
    case 5:
        return 453;
    case 6:
        return 1953;
    case 7:
        return 4535;
    case 8:
        return 14325;
    case 9:
        return 14291;
    case 10:
        return 54274;
    case 11:
        return 756;
    }
}
int getLie(int which)
{
    switch (which)
    {
    case 1:
        return 130;
    case 2:
        return 254;
    case 3:
        return 562;
    case 4:
        return 1011;
    case 5:
        return 2362;
    case 6:
        return 3799;
    case 7:
        return 8399;
    case 8:
        return 23075;
    case 9:
        return 37960;
    case 10:
        return 43577;
    case 11:
        return 85401;
    }
}


void showLie(unsigned int* m, int lie)
{
    for (int i = 0; i < lie; i++)
    {
        cout << m[i] << " ";
    }
    cout << endl;
}
unsigned int** init(int hang, int lie)
{
    unsigned int** m = new unsigned int* [hang];
    for (int i = 0; i < hang; i++)
    {
        m[i] = new unsigned int[lie];
        for (int p = 0; p < lie; p++)
        {
            m[i][p] = 0;
        }
    }
    return m;
}
int qujian(int nowliePos, int lie)
{
    return (lie - nowliePos - 1) / 32;
}
int liePos(int nowliePos, int lie)
{
    return lie - (((lie - nowliePos - 1) / 32) * 32 + nowliePos) - 1;
}
unsigned int bit2int(int* m)
{
    unsigned int result = 0;
    for (int i = 0; i < 32; i++)
    {
        if (m[i])result += pow(2, 31 - i);
    }
    return result;
}
void showM(unsigned int** m, int hang, int lie)
{
    for (int i = 0; i < hang; i++)
    {
        showLie(m[i], lie);
        cout << endl;
    }
}
int* int2bit(unsigned int decimal_num)
{
    int* pos = new int[32];
    unsigned int mask = 1 << 31; 
    for (int i = 0; i < 32; i++) {

        if ((decimal_num & mask) == 0) {
            pos[i] = 0;
        }
        else {
            pos[i] = 1;
        }

        mask = mask >> 1;
    }
    return pos;
}
void testShow(unsigned int** m, int hang, int lie, int lieOf01)
{
    int* temp;
    for (int i = 0; i < hang; i++)
    {
        for (int p = 0; p < lie; p++)
        {
            temp = int2bit(m[i][p]);
            for (int q = 0; q < 32; q++)
            {
                if (temp[q])
                {
                    cout << lieOf01 - 32 * p - q - 1 << " ";
                }
            }
        }
        cout << endl;
    }
}

unsigned int** write(string beiAddr, int beihang, int beilie, int rank, int numProcesses)
{
    int lie = (beilie / 32 * 32 == beilie) ? beilie / 32 : beilie / 32 + 1;
    int yu = lie - beilie;
    unsigned int** m = new unsigned int* [beihang];
    for (int i = 0; i < beihang; i++)
    {
        m[i] = new unsigned int[lie];
        for (int p = 0; p < lie; p++)
            m[i][p] = 0;
    }
    ifstream fin;
    fin.open(beiAddr.c_str(), ios::in);
    int* pos = new int[32];
    for (int i = 0; i < 32; i++)
        pos[i] = 0;
    char ch;
    int temp = 0, nowPos = 0, bitclimiter = 0, whetherBegin = 1, nowQujian = 0, lastQujian = 0;
  

    while (fin.get(ch))
    {
        if (ch >= '0' && ch <= '9')
        {
            temp *= 10;
            temp += ch - '0';
        }
        else if (ch == ' ')
        {
            if (whetherBegin)
            {
                lastQujian = qujian(temp, beilie); 
                bitclimiter = liePos(temp, beilie);
                pos[bitclimiter] = 1;
                whetherBegin = 0;
            }
            else
            {
                nowQujian = qujian(temp, beilie);
                if (nowQujian != lastQujian)
                {
                    m[nowPos][lastQujian] = bit2int(pos);
                    for (int i = 0; i < 32; i++)
                        pos[i] = 0;
                }
                bitclimiter = liePos(temp, beilie);
                pos[bitclimiter] = 1;
                lastQujian = nowQujian;
            }
            temp = 0;
        }
        else if (ch == '\n')
        {
            m[nowPos][lastQujian] = bit2int(pos);
            for (int i = 0; i < 32; i++)
                pos[i] = 0;
            whetherBegin = 1;
            nowPos++;
            temp = 0;
            nowQujian = 0;
            lastQujian = 0;
        }
    }
    fin.close();


    return m;
}
unsigned int** MPIwrite(string beiAddr, int beihang, int beilie, int rank, int numProcesses)
{
    int lie = (beilie / 32 * 32 == beilie) ? beilie / 32 : beilie / 32 + 1;
    int yu = lie - beilie;
    unsigned int** m = new unsigned int* [beihang];
    for (int i = 0; i < beihang; i++)
    {
        m[i] = new unsigned int[lie];
        for (int p = 0; p < lie; p++)
            m[i][p] = 0;
    }
    ifstream fin;
    fin.open(beiAddr.c_str(), ios::in);
    int* pos = new int[32];
    for (int i = 0; i < 32; i++)
        pos[i] = 0;
    char ch;
    int temp = 0, nowPos = 0, bitclimiter = 0, whetherBegin = 1, nowQujian = 0, lastQujian = 0;
    int howmany_hang_i_will_process = (beihang == (beihang / numProcesses) * numProcesses) ? beihang / numProcesses : beihang / numProcesses + 1;
    int startLine = howmany_hang_i_will_process * rank;



    for (int i = 0; i < startLine; i++)
    {
        fin.ignore(1145141919, '\n');
    }

    while (fin.get(ch) && nowPos < howmany_hang_i_will_process)
    {
        if (ch >= '0' && ch <= '9')
        {
            temp *= 10;
            temp += ch - '0';
        }
        else if (ch == ' ')
        {
            if (whetherBegin)
            {
                lastQujian = qujian(temp, beilie); 
                bitclimiter = liePos(temp, beilie);
                pos[bitclimiter] = 1;
                whetherBegin = 0;
            }
            else
            {
                nowQujian = qujian(temp, beilie);
                if (nowQujian != lastQujian)
                {
                    m[nowPos + startLine][lastQujian] = bit2int(pos);
                    for (int i = 0; i < 32; i++)
                        pos[i] = 0;
                }
                bitclimiter = liePos(temp, beilie);
                pos[bitclimiter] = 1;
                lastQujian = nowQujian;
            }
            temp = 0;
        }
        else if (ch == '\n')
        {
            m[nowPos + startLine][lastQujian] = bit2int(pos);
            for (int i = 0; i < 32; i++)
                pos[i] = 0;
            whetherBegin = 1;
            nowPos++;
            temp = 0;
            nowQujian = 0;
            lastQujian = 0;
        }
    }
    fin.close();


    for (int i = 0; i < beihang; i++)
    {
        if (i >= startLine && i < startLine + howmany_hang_i_will_process)
        {

            for (int j = 0; j < numProcesses; j++)
            {
                if (j != rank)
                    MPI_Send(&m[i][0], lie, MPI_UNSIGNED, j, 0, MPI_COMM_WORLD);
            }
        }
        else
        {

            MPI_Recv(&m[i][0], lie, MPI_UNSIGNED, i / howmany_hang_i_will_process, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        }
    }


    return m;
}




struct TransportData {
    int process_start_at_here;
    int temp;
};


int fuckTimes = 0;

streampos MPIUpdateZi(unsigned** zi, int howmany, int zilie, int lie, int beginHang, ifstream& fin, streampos headPos, int rank, int numProcesses)
{
    int pos[32];
    for (int i = 0; i < howmany; i++)
        for (int p = 0; p < lie; p++)
            zi[i][p] = 0;
    for (int i = 0; i < 32; i++)
        pos[i] = 0;
    streampos nowHead = headPos;
    fin.seekg(headPos);
    char ch;
    int temp = 0, nowPos = 0, bitclimiter = 0, whetherBegin = 1, nowQujian = 0, lastQujian = 0, thisishang = 0, dotimes = 0;

    fuckTimes++;



    int** fenpei_recorderArr = new int* [howmany + 1];
    for (int i = 0; i < howmany; i++)
    {
        fenpei_recorderArr[i] = new int[2];
    }
    int fenpei_recorderSize = 0;
    

    streampos process_start_at_here = 0;
    int which_process_is_now = 1;

    while (dotimes < howmany)
    {
        if (!fin.get(ch))
        {
            if (rank == 0)
            {
                break;
            }
            else
            {
                MPI_Recv(&fenpei_recorderArr[fenpei_recorderSize][0], 2, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                break;
            }
        }
        if (ch >= '0' && ch <= '9')
        {
            temp *= 10;
            temp += ch - '0';
        }
        else if (ch == ' ')
        {
            if (whetherBegin)
            {
                if (temp < beginHang - howmany)
                {
                    if (rank == 0)
                        break;
                    else
                    {
                        MPI_Recv(&fenpei_recorderArr[fenpei_recorderSize][0], 2, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
                        break;
                    }
                }
                else
                {

                    if (rank == 0)
                    {

                        lastQujian = qujian(temp, zilie);
                        bitclimiter = liePos(temp, zilie);
                        pos[bitclimiter] = 1;
                        whetherBegin = 0;
                        thisishang = beginHang - temp - 1;



                        process_start_at_here = fin.tellg();


                        fenpei_recorderArr[fenpei_recorderSize][0] = process_start_at_here;
                        fenpei_recorderArr[fenpei_recorderSize][1] = temp;


                        MPI_Send(&fenpei_recorderArr[fenpei_recorderSize][0], 2, MPI_INT, which_process_is_now, 0, MPI_COMM_WORLD);

                        fenpei_recorderSize++;

                        which_process_is_now = (numProcesses - 1 == which_process_is_now) ? 1 : which_process_is_now + 1;



                        fin.ignore(1145141919, '\n');
        
                        nowHead = fin.tellg();
                        for (int i = 0; i < 32; i++)
                            pos[i] = 0;
                        whetherBegin = 1;
                        dotimes++;
                        temp = 0;
                        nowQujian = 0;
                        lastQujian = 0;
                        continue;
                    }
                    else
                    {


                        MPI_Recv(&fenpei_recorderArr[fenpei_recorderSize][0], 2, MPI_INT, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);


                        if (fenpei_recorderArr[fenpei_recorderSize][1] == -1)
                        {
                            break;
                        }


                        temp = fenpei_recorderArr[fenpei_recorderSize][1];

                        fin.seekg(fenpei_recorderArr[fenpei_recorderSize][0]);

                        fenpei_recorderSize++;


                        lastQujian = qujian(temp, zilie);
                        bitclimiter = liePos(temp, zilie);
                        pos[bitclimiter] = 1;
                        whetherBegin = 0;
                        thisishang = beginHang - temp - 1;

                    }


                }
            }
            else
            {
                nowQujian = qujian(temp, zilie);
                if (nowQujian != lastQujian)
                {
                    zi[thisishang][lastQujian] = bit2int(pos);
                    for (int i = 0; i < 32; i++)
                        pos[i] = 0;
                }
                bitclimiter = liePos(temp, zilie);
                pos[bitclimiter] = 1;
                lastQujian = nowQujian;
            }
            temp = 0;
        }
        else if (ch == '\n')
        {
            nowHead = fin.tellg();
            zi[thisishang][lastQujian] = bit2int(pos);
            for (int i = 0; i < 32; i++)
                pos[i] = 0;
            whetherBegin = 1;
            dotimes++;
            temp = 0;
            nowQujian = 0;
            lastQujian = 0;
        }
    }



    if (rank == 0)
    {
        MPI_Request request;

        int temp[2] = { -1,-1 };

        for (int i = 1; i < numProcesses; i++)
        {
            MPI_Isend(&temp, 2, MPI_INT, i, 0, MPI_COMM_WORLD, &request);
        }
    }



    if (rank == 0)
    {
        for (int i = 0; i < fenpei_recorderSize; i += (numProcesses - 1))
        {

            for (int j = 1; j < numProcesses && i + j <= fenpei_recorderSize; j++)
            {
                MPI_Recv(&zi[beginHang - fenpei_recorderArr[i + j - 1][1] - 1][0], lie, MPI_UNSIGNED, j, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            }
        }

    }
    else
    {

        for (int i = 0; i < fenpei_recorderSize; i++)
        {
            MPI_Send(&zi[beginHang - fenpei_recorderArr[i][1] - 1][0], lie, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
        }
    }



    delete[]fenpei_recorderArr;
    MPI_Bcast(&nowHead, 1, MPI_OFFSET, 0, MPI_COMM_WORLD);





    return nowHead;
}
streampos UpdateZi(unsigned** zi, int howmany, int zilie, int lie, int beginHang, ifstream& fin, streampos headPos)
{

    int pos[32];
    for (int i = 0; i < howmany; i++)
        for (int p = 0; p < lie; p++)
            zi[i][p] = 0;
    for (int i = 0; i < 32; i++)
        pos[i] = 0;
    streampos nowHead = headPos;
    fin.seekg(headPos);
    char ch;
    int temp = 0, nowPos = 0, bitclimiter = 0, whetherBegin = 1, nowQujian = 0, lastQujian = 0, thisishang = 0, dotimes = 0;


    while (dotimes < howmany && fin.get(ch))
    {
        if (ch >= '0' && ch <= '9')
        {
            temp *= 10;
            temp += ch - '0';
        }
        else if (ch == ' ')
        {
            if (whetherBegin)
            {
                if (temp < beginHang - howmany)
                {
                    break;
                }
                else
                {
                    lastQujian = qujian(temp, zilie);
                    bitclimiter = liePos(temp, zilie);
                    pos[bitclimiter] = 1;
                    whetherBegin = 0;
                    thisishang = beginHang - temp - 1;
                }
            }
            else
            {
                nowQujian = qujian(temp, zilie);

                if (nowQujian != lastQujian)
                {
                    zi[thisishang][lastQujian] = bit2int(pos);
                    for (int i = 0; i < 32; i++)
                        pos[i] = 0;
                }
                bitclimiter = liePos(temp, zilie);
                pos[bitclimiter] = 1;
                lastQujian = nowQujian;
            }
            temp = 0;
        }
        else if (ch == '\n')
        {
            nowHead = fin.tellg();
            zi[thisishang][lastQujian] = bit2int(pos);
            for (int i = 0; i < 32; i++)
                pos[i] = 0;
            whetherBegin = 1;
            dotimes++;
            temp = 0;
            nowQujian = 0;
            lastQujian = 0;
        }
    }


    return nowHead;
}
int findinthead(unsigned int num, int lie, int qujian)
{
    int* pos = int2bit(num);
    for (int i = 0; i < 32; i++)
    {
        if (pos[i])
        {
            return lie - qujian * 32 - i - 1;
        }
    }
    return -1;
}
int findHead(unsigned int* m, int lie)
{
    for (int i = 0; i < lie; i++)
    {
        if (m[i])
        {
            return findinthead(m[i], lie, i);
        }
    }
    return -1;
}


bool isNotNull(unsigned int* m, int lie)
{
    for (int i = 0; i < lie; i++)
    {
        if (m[i])
        {
            return 1;
        }
    }
    return 0;
}
void AsubB(unsigned int* a, unsigned int* b, int lie)
{
    for (int i = 0; i < lie; i++)
    {
        a[i] = a[i] ^ b[i];
    }
}
void bingxingAsubB(unsigned int* a, unsigned int* b, int lie)
{
    int i = 0;
    for (i = 0; i + 4 < lie; i += 4)
    {
        uint32x4_t t1 = vld1q_u32(&a[i]);
        uint32x4_t t2 = vld1q_u32(&b[i]);
        t1 = veorq_u32(t1, t2);
        vst1q_u32(&a[i], t1);
    }

    for (; i < lie; i++)
    {
        a[i] = (a[i] == b[i]) ? 0 : 1;
    }


}


double common(unsigned** bei, int howmany, int beihang, int beilie, int zihang, int zilie, int whichTextIsNow, int bingOrCom)
{
    struct timeval t1, t2;
    double timeuse = 0;
    string ziAddr = getziAddr(whichTextIsNow);
    ifstream fin;
    fin.open(ziAddr.c_str(), ios::in);
    int lie = (beilie / 32 * 32 == beilie) ? beilie / 32 : beilie / 32 + 1;
    unsigned int** zi = init(howmany, lie);
    isNull = new bool[howmany];
    int beginHang = zihang;
    int times = (zihang / howmany * howmany == zihang) ? zihang / howmany : zihang / howmany + 1;
    streampos headPos = 0;
    bool* wetherThisHangIsOk = new bool[beihang];
    for (int i = 0; i < beihang; i++)
        wetherThisHangIsOk[i] = 0;
    int beishufuck = 1;
    for (int cycles = 0; cycles < times; cycles++)
    {
        

        for (int i = 0; i < howmany; i++)
            isNull[i] = !isNotNull(zi[i], lie);
        gettimeofday(&t1, NULL);

        beginHang = zihang - cycles * howmany;
        headPos = UpdateZi(zi, howmany, zilie, lie, beginHang, fin, headPos);



        for (int beiPos = 0; beiPos < beihang; beiPos++)
        {
            for (int ziPos = beginHang - 1; ziPos >= beginHang - howmany; ziPos--)
            {
                if (wetherThisHangIsOk[beiPos])
                    break;
                int nowHead = 0;
                int whetherBreak = 0;
                nowHead = findHead(bei[beiPos], zilie);
                if (nowHead >= beginHang - howmany && nowHead < beginHang)
                {

                    if (isNull[beginHang - nowHead - 1] == 0)
                        AsubB(bei[beiPos], zi[beginHang - nowHead - 1], lie);
                    else
                    {
                        wetherThisHangIsOk[beiPos] = 1;
                        for (int qqq = 0; qqq < lie; qqq++)
                            zi[beginHang - nowHead - 1][qqq] = bei[beiPos][qqq];
                        isNull[beginHang - nowHead - 1] = 0;
                    }

                }
                else ziPos = -114514;
            }
        }


        gettimeofday(&t2, NULL);
        timeuse += (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec) / 1000000.0;
    }

    return timeuse;
}

double common2(int numProcesses, int rank, int argc, char* argv[], unsigned** bei, int howmany, int beihang, int beilie, int zihang, int zilie, int whichTextIsNow, int bingOrCom)
{




    struct timeval t1, t2;
    double timeuse = 0;
    string ziAddr = getziAddr(whichTextIsNow);
    ifstream fin;
    fin.open(ziAddr.c_str(), ios::in);
    int lie = (beilie / 32 * 32 == beilie) ? beilie / 32 : beilie / 32 + 1;
    unsigned int** zi = init(howmany, lie);
    isNull = new bool[howmany];
    int beginHang = zihang;
    int times = (zihang / howmany * howmany == zihang) ? zihang / howmany : zihang / howmany + 1;
    streampos headPos = 0;
    bool* wetherThisHangIsOk = new bool[beihang];
    for (int i = 0; i < beihang; i++)
        wetherThisHangIsOk[i] = 0;
    int beishufuck = 1;

    for (int cycles = 0; cycles < times; cycles++)
    {
        if (times * beishufuck / 10 <= cycles)
        {
            beishufuck++;
        }





        if (rank == 0)
            gettimeofday(&t1, NULL);

        beginHang = zihang - cycles * howmany;
        headPos = MPIUpdateZi(zi, howmany, zilie, lie, beginHang, fin, headPos, rank, numProcesses);



        if (rank == 0)
        {
            for (int i = 0; i < howmany; i++)
                isNull[i] = !isNotNull(zi[i], lie);
#pragma omp parallel num_threads(pThreadNum)
#pragma omp for
            for (int beiPos = 0; beiPos < beihang; beiPos++)
            {
                for (int ziPos = beginHang - 1; ziPos >= beginHang - howmany; ziPos--)
                {
                    if (wetherThisHangIsOk[beiPos])

                        break;
                    int nowHead = 0;
                    int whetherBreak = 0;
                    nowHead = findHead(bei[beiPos], zilie);
#pragma omp critical
                    {
                        if (nowHead >= beginHang - howmany && nowHead < beginHang)
                        {
                            if (isNull[beginHang - nowHead - 1] == 0)
                                bingxingAsubB(bei[beiPos], zi[beginHang - nowHead - 1], lie);
                            else
                            {
                                wetherThisHangIsOk[beiPos] = 1;
                                for (int qqq = 0; qqq < lie; qqq++)
                                    zi[beginHang - nowHead - 1][qqq] = bei[beiPos][qqq];
                                isNull[beginHang - nowHead - 1] = 0;
                            }

                        }
                        else ziPos = -114514;
                    }
                }
            }
        }




        if (rank == 0)
        {
            gettimeofday(&t2, NULL);
            timeuse += (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec) / 1000000.0;
        }
    }


    fin.close();
    return timeuse;
}

int main(int argc, char* argv[])
{

    MPI_Init(&argc, &argv);
    int numProcesses, rank;
    MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    pThreadNum = 3;
    if (1)
    {

        for (int i = 1; i <= 1; i++)
        {
            struct timeval t1, t2;
            double timeuse = 0;
            if (rank == 0)
            {
                gettimeofday(&t1, NULL);
            }

            int beihang, beilie, zihang, zilie;
            int whichTextIsNow = i;
            beihang = getHang(whichTextIsNow);
            beilie = zihang = zilie = getLie(whichTextIsNow);
            string beiAddr = getbeiAddr(whichTextIsNow);
            unsigned int** bei = MPIwrite(beiAddr, beihang, beilie, rank, numProcesses);

            int howmany = 1000;

            double time = common2(numProcesses, rank, argc, argv, bei, howmany, beihang, beilie, zihang, zilie, whichTextIsNow, 0);
            if (rank == 0)
            {
                gettimeofday(&t2, NULL);
                timeuse += (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec) / 1000000.0;
                cout << timeuse << endl;
            }
        }
    }
    else
    {

        for (int i = 11; i <= 11; i++)
        {
            struct timeval t1, t2;
            double timeuse = 0;
            gettimeofday(&t1, NULL);

            int beihang, beilie, zihang, zilie;
            int whichTextIsNow = i;
            beihang = getHang(whichTextIsNow);
            beilie = zihang = zilie = getLie(whichTextIsNow);
            string beiAddr = getbeiAddr(whichTextIsNow);
            unsigned int** bei = write(beiAddr, beihang, beilie, 0, 0);


            int howmany = 1000;

            double time = common(bei, howmany, beihang, beilie, zihang, zilie, whichTextIsNow, 0);
            gettimeofday(&t2, NULL);
            timeuse += (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec) / 1000000.0;
            cout << timeuse << endl;
        }
    }
    return 0;
}

